package org.jhotdraw.samples.phototemplate;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;
import javax.swing.JViewport;
import org.jhotdraw.app.DefaultMenuBuilder;
import org.jhotdraw.draw.AbstractFigure;
import org.jhotdraw.draw.AttributeKey;
import org.jhotdraw.draw.AttributeKeys;
import org.jhotdraw.draw.DefaultDrawing;
import org.jhotdraw.draw.DefaultDrawingEditor;
import org.jhotdraw.draw.DefaultDrawingView;
import org.jhotdraw.draw.Drawing;
import org.jhotdraw.draw.DrawingEditor;
import org.jhotdraw.draw.Figure;
import org.jhotdraw.draw.ImageFigure;
import org.jhotdraw.draw.ImageHolderFigure;
import org.jhotdraw.draw.QuadTreeDrawing;
import org.jhotdraw.draw.action.ButtonFactory;
import org.jhotdraw.draw.event.FigureAdapter;
import org.jhotdraw.draw.event.FigureEvent;
import org.jhotdraw.draw.event.FigureListener;
import org.jhotdraw.draw.io.ImageInputFormat;
import org.jhotdraw.draw.io.ImageOutputFormat;
import org.jhotdraw.draw.io.InputFormat;
import org.jhotdraw.draw.io.OutputFormat;
import org.jhotdraw.draw.io.SerializationInputOutputFormat;
import org.jhotdraw.draw.io.TextInputFormat;
import org.jhotdraw.draw.tool.CreationTool;
import org.jhotdraw.draw.tool.DnDTracker;
import org.jhotdraw.draw.tool.SelectionTool;
import org.jhotdraw.draw.tool.TextAreaCreationTool;
import org.jhotdraw.gui.plaf.palette.PaletteButtonUI;
import org.jhotdraw.samples.svg.SVGAttributeKeys;
import org.jhotdraw.samples.svg.SVGCreateFromFileTool;
import org.jhotdraw.samples.svg.figures.SVGGroupFigure;
import org.jhotdraw.samples.svg.figures.SVGImageFigure;
import org.jhotdraw.samples.svg.figures.SVGRectFigure;
import org.jhotdraw.samples.svg.figures.SVGTextAreaFigure;
import org.jhotdraw.samples.svg.figures.SVGTextFigure;
import org.jhotdraw.samples.svg.gui.FontToolBar;
import org.jhotdraw.samples.svg.gui.ViewToolBar;
import org.jhotdraw.samples.svg.io.ImageMapOutputFormat;
import org.jhotdraw.samples.svg.io.SVGInputFormat;
import org.jhotdraw.samples.svg.io.SVGOutputFormat;
import org.jhotdraw.samples.svg.io.SVGZInputFormat;
import org.jhotdraw.samples.svg.io.SVGZOutputFormat;
import org.jhotdraw.util.ResourceBundleUtil;

/**
 *
 * @author Eliazar
 */
public class PanelTemplate extends javax.swing.JPanel {

    private DrawingEditor editor;
    private DefaultDrawingView view;
    private Dimension size;
    private SVGRectFigure canvasRectangule;
    private int screenResolution;
    private final Double STROKE_CANVAS_WIDTH = new Double(2);
    private final String fileExtension = ".pro3d";
    /**
     * Creates new form PanelTemplate
     */
    public PanelTemplate(Dimension size) {
        initComponents();        
        this.size = size;
        loadPanelTemplate();
        screenResolution = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
    }

    private void loadPanelTemplate() {
        editor = new DefaultDrawingEditor();
        view = new DefaultDrawingView();
        // adicionando as bordas
        size.setSize(size.getWidth() + STROKE_CANVAS_WIDTH * 2, size.getHeight() + STROKE_CANVAS_WIDTH * 2);
        view.setPreferredSize(size);
        view.setDrawing(new DefaultDrawing());

        editor.add(view);
        createToolbarPanelTemplate();
        JViewport viewport = new JViewport();
        viewport.setPreferredSize(new Dimension((int)size.getWidth() + 20, (int)size.getHeight()+20));
        viewport.add(view);
        paneScrollTemplate.setViewportView(viewport);
        addCanvasRectangule();
        addListeners();
    }

    private Map<SVGImageFigure, URI> mapFigures=new HashMap<SVGImageFigure, URI>();
    private void createToolbarPanelTemplate() {
        try {
            ResourceBundleUtil labels = ResourceBundleUtil.getBundle("org.jhotdraw.draw.Labels");
            AbstractButton btn;
            InputStream stream;
            
            SelectionTool selectionTool = new SelectionTool();
            //selectionTool.setDragTracker(new DnDTracker());
            btn = ButtonFactory.addSelectionToolTo(tb, editor, selectionTool);
            btn.setToolTipText("Selecionar");

            JButton btRec = new JButton();
            stream = this.getClass().getResourceAsStream("/org/jhotdraw/samples/phototemplate/images/createRectangle.png");
            btRec.setIcon(new ImageIcon(ImageIO.read(stream)));
            btRec.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    RectangulePropertiesDialog dialog = new RectangulePropertiesDialog(null, true);
                    dialog.setVisible(true);
                    Point point = dialog.getPoint();
                    Dimension dimension = dialog.getDimension();
                    if(point != null &&  dimension != null) {
                        SVGRectFigure rectFigure = new SVGRectFigure(point.getX() , point.getY(), dimension.getWidth(), dimension.getHeight());
                        rectFigure.set(SVGAttributeKeys.FILL_COLOR, Color.WHITE);
                        rectFigure.set(SVGAttributeKeys.STROKE_COLOR, Color.black);    
                        rectFigure.set(SVGAttributeKeys.FILL_OPACITY, 1D);
                        view.getDrawing().add(rectFigure);
                    }
                }
            });
            tb.add(btRec);
            /*btn = ButtonFactory.addToolTo(
                    tb, editor,
                    new CreationTool(new SVGRectFigure()),
                    "edit.createRectangle",
                    labels);
            btn.setToolTipText("Adicionar retângulo");*/
                
            Map attributes = new HashMap<AttributeKey, Object>();
            attributes.put(AttributeKeys.FILL_COLOR, Color.black);
            attributes.put(AttributeKeys.STROKE_COLOR, null);

            TextAreaCreationTool textAreaTool;
            textAreaTool = new TextAreaCreationTool(new SVGTextAreaFigure(), attributes);
            btn = ButtonFactory.addToolTo(tb, editor, textAreaTool, "createTextArea", labels);
            stream = this.getClass().getResourceAsStream("/org/jhotdraw/draw/action/images/createTextArea.png");
            btn.setIcon(new ImageIcon(ImageIO.read(stream)));
            btn.setToolTipText("Adicionar texto");

            SVGCreateFromFileTool imageTool;
            /*attributes = new HashMap<AttributeKey, Object>();
            attributes.put(AttributeKeys.FILL_COLOR, null);
            attributes.put(AttributeKeys.STROKE_COLOR, null);
            btn = ButtonFactory.addToolTo(tb, editor, imageTool = new SVGCreateFromFileTool(new SVGImageFigure(), new SVGGroupFigure(), attributes), "createImage", labels);
            imageTool.setToolDoneAfterCreation(true);
            imageTool.setUseFileDialog(true);*/
            JButton btLoadImage = new JButton();
            stream = this.getClass().getResourceAsStream("/org/jhotdraw/draw/action/images/createImage.png");
            btLoadImage.setIcon(new ImageIcon(ImageIO.read(stream)));
            btLoadImage.setToolTipText("Adicionar imagem");
            btLoadImage.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JFileChooser chooser = new JFileChooser(Utilities.getProperty(Utilities.KEY.DIR_FOTOS));
                    if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                        try {                            
                            ImageHolderFigure holderFigure = (ImageHolderFigure) new SVGImageFigurePhotoTemplate(null);
                            holderFigure.loadImage(chooser.getSelectedFile());
                            holderFigure.setBounds(
                                new Point2D.Double(0, 0),
                                new Point2D.Double(
                                holderFigure.getBufferedImage().getWidth(),
                                holderFigure.getBufferedImage().getHeight()));                                    
                            ((SVGImageFigurePhotoTemplate)holderFigure).setImageUri(chooser.getSelectedFile().toURI());
                            view.getDrawing().add(holderFigure);                            
                        } catch (IOException ex) {
                            MessageDialog.showMessageFail(null, "Uma falha ocorreu ao carregar o arquivo.");
                        }
                    }
                }
            });
            tb.add(btLoadImage);
            
            JButton btSave = new JButton();
            stream = this.getClass().getResourceAsStream("/org/jhotdraw/draw/action/images/fileSave.png");
            btSave.setIcon(new ImageIcon(ImageIO.read(stream)));
            btSave.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    saveTemplate();
                }
            });
            btSave.setToolTipText("Salvar template");
            tb.add(btSave);

            JButton btFont = new JButton();
            stream = this.getClass().getResourceAsStream("/org/jhotdraw/samples/phototemplate/images/attributeFont.png");
            btFont.setIcon(new ImageIcon(ImageIO.read(stream)));
            btFont.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    FontAttributeDialog attributeDialog = new FontAttributeDialog(null, true, editor);
                    attributeDialog.setVisible(true);
                }
            });
            btFont.setToolTipText("Configurar fonte");
            tb.add(btFont);
            
            
            btn = ButtonFactory.createZoomButton(view, new double[]{2, 1.5, 1.25, 1, 0.75, 0.5, 0.25});
            btn.setUI((PaletteButtonUI) PaletteButtonUI.createUI(btn));
            labels.configureToolBarButton(btn, "view.zoomFactor");
            btn.setText("100%");
            btn.setToolTipText("Zoom");
            tb.add(btn);                                   
            
        } catch (Exception ex) {
            Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    private File getFileToSave() {       
        String fileFullName = Utilities.getProperty(Utilities.KEY.DIR_TEMPLATES);
        if(fileFullName == null || fileFullName.equals("")) {
            MessageDialog.showMessageFail(this, "Informe um diretório para salvar os templates, na opção Parâmetros do menu Configuração.");
        }else {
            if(!fileFullName.endsWith(Utilities.separator)) {
                fileFullName = fileFullName.concat(Utilities.separator);
            }
            String fileName = JOptionPane.showInputDialog(null, "Informe um nome para o template:", "Salvar template", JOptionPane.INFORMATION_MESSAGE);                        
            if(fileName != null && !fileName.trim().equals("")) {                                                            
                File file = new File(fileFullName.concat(fileName).concat(fileExtension));
                if (file.exists()) {
                    if (JOptionPane.showConfirmDialog(null, "O arquivo já existe. Deseja sobrescrevê-lo?") == JOptionPane.OK_OPTION) {
                        file.delete();                        
                        return file;
                    }
                } else {
                    return file;
                }
            }  
        }
        return null;
    }
    
    private void saveTemplate() {
        File file = getFileToSave();
        if(file != null) {
            try {
                removeAllFiguresOutPaperSize(); 
                createFileWithDimensionOfFigures(file);
                view.setSize(size);
                //new SVGOutputFormat().write(file, view.getDrawing());
                MessageDialog.showMessageOk(this);
            } catch (Exception ex) {
                ex.printStackTrace();
                MessageDialog.showMessageFailDefault(this);
            }
        }      
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tb = new javax.swing.JToolBar();
        paneScrollTemplate = new javax.swing.JScrollPane();

        tb.setFloatable(false);
        tb.setOrientation(javax.swing.SwingConstants.VERTICAL);
        tb.setRollover(true);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(tb, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(paneScrollTemplate, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(paneScrollTemplate, javax.swing.GroupLayout.DEFAULT_SIZE, 150, Short.MAX_VALUE)
            .addComponent(tb, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane paneScrollTemplate;
    private javax.swing.JToolBar tb;
    // End of variables declaration//GEN-END:variables

    private void addCanvasRectangule() {
        Map<AttributeKey, Object> attributes = new HashMap<AttributeKey, Object>();
        attributes.put(AttributeKeys.STROKE_COLOR, Color.black);
        attributes.put(AttributeKeys.STROKE_WIDTH, STROKE_CANVAS_WIDTH);
        attributes.put(SVGAttributeKeys.FILL_OPACITY, 0D);
        canvasRectangule = new SVGRectFigure(0, 0, size.getWidth(), size.getHeight());
        canvasRectangule.setAttributes(attributes);
        view.getDrawing().add(canvasRectangule);
        canvasRectangule.setSelectable(false);
    }

    private void removeAllFiguresOutPaperSize() {
        java.util.List<Figure> figuresToRemove = new ArrayList<Figure>();
        for (Figure figure : view.getDrawing().getChildren()) {
            if (figure != canvasRectangule) {
                if (!canvasRectangule.contains(figure.getStartPoint()) || !canvasRectangule.contains(figure.getEndPoint())) {
                    figuresToRemove.add(figure);
                }
            }
        }
        if (!figuresToRemove.isEmpty()) {
            view.getDrawing().removeAll(figuresToRemove);            
        }
    }

    private Drawing createDrawing() {
        Drawing drawing = new QuadTreeDrawing();
        LinkedList<InputFormat> inputFormats = new LinkedList<InputFormat>();
        inputFormats.add(new SVGZInputFormat());
        inputFormats.add(new SVGInputFormat());
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "PNG", "Portable Network Graphics (PNG)", "png", "image/png"));
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "JPG", "Joint Photographics Experts Group (JPEG)", "jpg", "image/jpg"));
        inputFormats.add(new ImageInputFormat(new SVGImageFigure(), "GIF", "Graphics Interchange Format (GIF)", "gif", "image/gif"));
        inputFormats.add(new TextInputFormat(new SVGTextFigure()));
        inputFormats.add(new SerializationInputOutputFormat());
        drawing.setInputFormats(inputFormats);

        LinkedList<OutputFormat> outputFormats = new LinkedList<OutputFormat>();
        outputFormats.add(new SVGOutputFormat());
        outputFormats.add(new SVGZOutputFormat());
        outputFormats.add(new ImageOutputFormat());
        outputFormats.add(new ImageOutputFormat("JPG", "Joint Photographics Experts Group (JPEG)", "jpg", BufferedImage.TYPE_INT_RGB));
        outputFormats.add(new ImageOutputFormat("BMP", "Windows Bitmap (BMP)", "bmp", BufferedImage.TYPE_BYTE_INDEXED));
        outputFormats.add(new ImageMapOutputFormat());
        outputFormats.add(new SerializationInputOutputFormat());
        drawing.setOutputFormats(outputFormats);

        return drawing;
    }
    
    private void createFileWithDimensionOfFigures(File file) {        
        BufferedWriter bw = null;        
        try {                                              
            file.createNewFile();            
            bw = new BufferedWriter(new FileWriter(file));            
            for (Figure figure : view.getDrawing().getChildren()) { 
                if(figure == canvasRectangule) {
                    bw.write("SIZE=" + UnitConv.px2mm(((SVGRectFigure)figure).getX(), screenResolution) + ";" + UnitConv.px2mm(((SVGRectFigure)figure).getY(), screenResolution) +  ";" + UnitConv.px2mm(((SVGRectFigure)figure).getWidth(), screenResolution) + ";" + UnitConv.px2mm(((SVGRectFigure)figure).getHeight(), screenResolution) + "\n");
                }else if(figure instanceof SVGRectFigure){
                    bw.write("REC=" + UnitConv.px2mm(((SVGRectFigure)figure).getX(), screenResolution) + ";" + UnitConv.px2mm(((SVGRectFigure)figure).getY(), screenResolution) +  ";" +  UnitConv.px2mm(((SVGRectFigure)figure).getWidth(), screenResolution) + ";" + UnitConv.px2mm(((SVGRectFigure)figure).getHeight(), screenResolution) + "\n");
                }else if(figure instanceof SVGImageFigurePhotoTemplate){
                    String uri = ((SVGImageFigurePhotoTemplate)figure).getImageUri().getPath();
                    if(uri.startsWith("/")) {
                        uri.replaceFirst("/", "");
                    }
                    bw.write("IMG=" + UnitConv.px2mm(((SVGImageFigure)figure).getX(), screenResolution) + ";" + UnitConv.px2mm(((SVGImageFigure)figure).getY(), screenResolution) +  ";" + UnitConv.px2mm(((SVGImageFigure)figure).getWidth(), screenResolution) + ";" + UnitConv.px2mm(((SVGImageFigure)figure).getHeight(), screenResolution) + ";" + uri + "\n");
                }else if(figure instanceof SVGTextAreaFigure){
                    bw.write("TXT="   + UnitConv.px2mm(figure.getDrawingArea().getX(), screenResolution) + ";" + UnitConv.px2mm(figure.getDrawingArea().getY(), screenResolution) +  ";" + UnitConv.px2mm(figure.getDrawingArea().getWidth(), screenResolution) + ";" + UnitConv.px2mm(figure.getDrawingArea().getHeight(), screenResolution) + ";" + ((SVGTextAreaFigure)figure).getText() + ";" +  ((SVGTextAreaFigure)figure).getFont().getName() + ";" +  ((SVGTextAreaFigure)figure).getFont().getStyle() + ";" +  ((SVGTextAreaFigure)figure).getFont().getSize() + ";"  + ((SVGTextAreaFigure)figure).getTextColor().getRGB() + "\n");                  
                }           
            }
        } catch (IOException ex) {
            if( file != null && file.exists()) {
                file.delete();                
            }
        } finally {
            try {
                bw.close();
            } catch (IOException ex) {
                Logger.getLogger(PanelTemplate.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }  

    private void addListeners() {
        view.getDrawing().addFigureListener(new FigureListener() {

            @Override
            public void areaInvalidated(FigureEvent fe) {
               
            }

            @Override
            public void attributeChanged(FigureEvent fe) {
               
            }

            @Override
            public void figureHandlesChanged(FigureEvent fe) {
               
            }

            @Override
            public void figureChanged(FigureEvent fe) {
               
            }

            @Override
            public void figureAdded(FigureEvent fe) {
                System.out.println("oi");
            }

            @Override
            public void figureRemoved(FigureEvent fe) {
                
            }

            @Override
            public void figureRequestRemove(FigureEvent fe) {
                
            }
        });
    }
}
